let obj = {
    age: 1,
    name: 'zs',
    ok: true,
    num: 10
}
const bucket = new WeakMap()
let activeEffectFn = null;
let activeStack = []
function track(target, key) {
    let deps = bucket.get(target)
    if (!deps) {
        bucket.set(target, deps = new Map())
    }
    let effectFns = deps.get(key)
    if (!effectFns) {
        deps.set(key, effectFns = new Set())
    }
    effectFns.add(activeEffectFn)
    activeEffectFn && activeEffectFn.deps.push(effectFns)
}
function trigger(target, key) {
    console.log(target,key,bucket);
    let deps = bucket.get(target)
    if (!deps) {
        return
    }
    let effectFns = deps.get(key)
    if (!effectFns) {
        return
    }
    const efectsToRun = new Set(effectFns);

    efectsToRun.forEach((activeFn) => {
        if (activeFn && activeEffectFn !== activeFn) {
            if (activeFn.options && activeFn.options.schelder) {
                activeFn.options.schelder(activeFn)
            } else {
                activeFn();
            }
        }
    });
}

let handle = {
    get(target, key) {
        track(target, key)
        return target[key]
    },
    set(target, key, newValue) {
        target[key] = newValue
        trigger(target, key)
        return true
    }
}
function cleanup(activeFn) {
    for (let i = 0; i < activeFn.deps.length; i++) {
        const effectfns = activeFn.deps[i];
        effectfns.delete(activeFn)
    }
    activeFn.deps.length = 0
}
// 响应式初级版
let proxy = new Proxy(obj, handle)
function effect(effectFn, options) {
    function activeFn() {
        cleanup(activeFn)
        activeStack.push(activeFn)
        activeEffectFn = activeFn
        let res = effectFn()
        activeStack.pop()
        activeEffectFn = activeStack[activeStack.length - 1]
        return res
    }
    activeFn.deps = []
    activeFn.options = options
    if (options && options.lazy) {
        return activeFn
    }
    activeFn()
}

function computed(getter) {
    let cache;
    let activeFn = effect(getter, {
        schelder: function (effectfn) {
            console.log('set');
            cache = false
            trigger(obj, 'value')
        },
        lazy: true
    })
    let res = activeFn()
    let obj = {
        get value() {
            if (!cache) {
                track(obj, 'value')
                cache=true
                res = activeFn()
                console.log('no cache');
            }
            return res
        }
    }
    return obj
}


let simulate = computed(() => {
    return proxy.age + proxy.num
})


// computed属性的实现
// 1 computed属性要有proxy属性的特性
// 特性1 当依赖属性发生变化的时候 computed属性要重新计算
// 特性2 访问computed属性的时候 需要有缓存效果
effect(() => {
    console.log('zhix');
    console.log(simulate.value);
})
// 当依赖属性age发生变化的时候 上面的依赖要重新执行
proxy.age = 4